<html>
<head>
<title>firstworks   Using the SQL Relay drop-in replacement library for MySQL</title>
<link href="../css/styles.css" rel="stylesheet">
</head>
<body>

<span class="heading1">Using the SQL Relay drop-in replacement library for MySQL</span><br><br>

<ul>
<li><a href="#whatis">What is a drop-in replacement library?</a></li>
<li><a href="#commandline">Using the drop-in replacement library with command-line programs</a></li>
<li><a href="#daemons">Using the drop-in replacement library with daemons</a></li>
<li><a href="#inetd">Using the drop-in replacement library with inetd/xinetd helper programs</a></li>
<li><a href="#php">Using the drop-in replacement library with PHP</a></li>
<li><a href="#modules">Using the drop-in replacement library with modules</a></li>
<li><a href="#work">Function support</a></li>
</ul>

<br>
<a name="whatis"></a>
<span class="heading2">What is a drop-in replacement library?</span><br>

<p>The SQL Relay drop-in replacement library for MySQL clients allows you to
run an application that was written using the native MySQL client API against
SQL Relay without rewriting the application.</p>

<p>The drop-in replacement library is a shared object library that implements
MySQL client library functions as calls to similar SQL Relay API functions
which then map the results back into native MySQL client data structures.</p>

<p>There are a variety of reasons that you might want to use the SQL Relay
drop-in replacement library for MySQL clients.  An application written for
MySQL could, for instance, be made to run queries against an Oracle or
Microsoft SQL Server database without modification.  Or you could simply put
SQL Relay between an application and the MySQL database that it normally runs
against to take advantage of SQL Relay's persistence, load balancing or
throttling facilities.</p>

<br>
<a name="commandline"></a>
<span class="heading2">Using the drop-in replacement library with command-line programs</span><br>

<p>To use the SQL Relay drop-in replacement library for MySQL clients, you first
need to determine what version of MySQL your existing application was compiled
against.  There are 4 different drop-in replacement libraries.  One each for
MySQL versions 3.xx, 4.0, 4.1, 5.0 and 5.1.  MySQL's native data structures
changed a bit between the different versions.  If you use the wrong library your
program will most likely crash.</p>

<p>You can find out which library your program uses by running the following
command.  In this example, the command checks the "mysql" program; the command
line client that comes with the MySQL distribution.</p>

<blockquote><pre><b>
ldd /usr/bin/mysql
</b></pre></blockquote>

<p>It should return something like the following:</p>

<blockquote><pre>
libreadline.so.4 =&gt; /usr/lib/libreadline.so.4 (0x00625000)
libncurses.so.5 =&gt; /usr/lib/libncurses.so.5 (0x00976000)
<b>libmysqlclient.so.10 =&gt; /usr/lib/mysql/libmysqlclient.so.10 (0x009b8000)</b>
libz.so.1 =&gt; /usr/lib/libz.so.1 (0x00963000)
libcrypt.so.1 =&gt; /lib/libcrypt.so.1 (0x003dc000)
libnsl.so.1 =&gt; /lib/libnsl.so.1 (0x003c5000)
libstdc++.so.5 =&gt; /usr/lib/libstdc++.so.5 (0x002ff000)
libm.so.6 =&gt; /lib/tls/libm.so.6 (0x008ba000)
libgcc_s.so.1 =&gt; /lib/libgcc_s.so.1 (0x003bb000)
libc.so.6 =&gt; /lib/tls/libc.so.6 (0x0077f000)
libgpm.so.1 =&gt; /usr/lib/libgpm.so.1 (0x006d1000)
/lib/ld-linux.so.2 =&gt; /lib/ld-linux.so.2 (0x00767000)
</pre></blockquote>

<p>The line in bold above is the important line.</p>

<p>The 10 at the end of libmysqlclient.so.10 means MySQL protocol version 10.
If your application links against version 10 or lower then you can use the
MySQL 3.xx version of the drop-in library.  If it links against version 11 or
12 then you need to use the MySQL 4.0 version of the drop-in library.  If it
links against version 13 then you need to use the MySQL 4.1 version of the
drop-in library.  If it links against version 14 then you may need to use the
MySQL 4.1 or 5.0 version of the drop-in library.  MySQL 4.1 and 5.0 both use
the same protocol version (so far) but there are differences in the data
structures, so you'll have to figure out which version it uses some other
way.</p>

<p>Once you've figured out which version of MySQL your program was compiled
against, you can load the appropriate drop in library and run your program.</p>

<p>The parameters that would ordinarily indicate which host, port, socket,
username and password to use to connect to MySQL will be used as parameters to
connect to SQL Relay.  The parameter that would ordinarily indicate which
database to connect to will be ignored.  Instances of SQL Relay are configured
to connect to a single database, and that database will be used by the client
program.</p>

<p>In the following example, we're running the "mysql" program against an
instance of SQL Relay running on the localhost, port 8009 against an Oracle
database.  This instance of SQL Relay is configured with a username/password
of oracle8user/oracle8pass.</p>

<p>For sh-based shells:</p>

<blockquote><pre><b>
LD_PRELOAD=/usr/local/firstworks/lib/libmysql3sqlrelay.so
export LD_PRELOAD
mysql -h localhost -P 8009 --user=oracle8user --password=oracle8pass
</b></pre></blockquote>

<p>For csh-based shells:</p>

<blockquote><pre><b>
setenv LD_PRELOAD /usr/local/firstworks/lib/libmysql3sqlrelay.so
mysql -h localhost -P 8009 --user=oracle8user --password=oracle8pass
</b></pre></blockquote>

<p>The LD_PRELOAD environment variable instructs the dynamic loader to load
libmysql3sqlrelay.so before loading any other libraries for any programs.
The mysql client program will still load the native MySQL client library, but
since it loaded the SQL Relay drop-in replacement library first, function calls
that would normally be fulfilled by the native MySQL client library are 
fulfilled by the SQL Relay drop-in replacement library instead.</p>

<p>If your application was compiled against a different version of MySQL, you
will need to replace libmysql3sqlrelay.so with a different library.
The following table indicates which library is required for each version of
MySQL.</p>

<table border="1">
<tr><th>Version of MySQL</th><th>Library</th></tr>
<tr><td align="center">3.x</td><td>libmysql3sqlrelay.so</td></tr>
<tr><td align="center">4.0.x</td><td>libmysql40sqlrelay.so</td></tr>
<tr><td align="center">4.1.x</td><td>libmysql41sqlrelay.so</td></tr>
<tr><td align="center">5.0.x</td><td>libmysql50sqlrelay.so</td></tr>
<tr><td align="center">5.1.x</td><td>libmysql51sqlrelay.so</td></tr>
</table>

<p>Below is a sample session using the mysql command line client against an
Oracle database through SQL Relay.</p>

<blockquote>
<pre>
Welcome <font color="#6b59ce">to</font> the MySQL monitor.  Commands <font color="#6b59ce">end</font> <font color="#6b59ce">with</font> ; <font color="#a52829"><b>or</b></font> \g.
Your MySQL connection id <font color="#6b59ce">is</font> <font color="#ff00ff">0</font> <font color="#6b59ce">to</font> server version: <font color="#ff00ff">3</font>.<font color="#ff00ff">23</font>.<font color="#ff00ff">58</font>

<font color="#6b59ce">Type</font> <font color="#ff00ff">'help;'</font> <font color="#a52829"><b>or</b></font> <font color="#ff00ff">'\h'</font> <font color="#6b59ce">for</font> help. <font color="#6b59ce">Type</font> <font color="#ff00ff">'\c'</font> <font color="#6b59ce">to</font> clear the buffer.

mysql&gt; <font color="#a52829"><b>create</b></font> <font color="#6b59ce">table</font> testtable (col1 <font color="#298a52"><b>varchar2</b></font>(<font color="#ff00ff">60</font>), col2 <font color="#298a52"><b>number</b></font>(<font color="#ff00ff">5</font>,<font color="#ff00ff">2</font>));
Empty <font color="#a52829"><b>set</b></font> (<font color="#ff00ff">0</font>.<font color="#ff00ff">21</font> sec)


mysql&gt; <font color="#a52829"><b>insert</b></font> <font color="#6b59ce">into</font> testtable <font color="#6b59ce">values</font> (<font color="#ff00ff">'hello'</font>,<font color="#ff00ff">123</font>.<font color="#ff00ff">45</font>);
Empty <font color="#a52829"><b>set</b></font> (<font color="#ff00ff">0</font>.<font color="#ff00ff">00</font> sec)


mysql&gt; <font color="#a52829"><b>select</b></font> * <font color="#6b59ce">from</font> testtable;
+<font color="#0000ff">-------+--------+</font>
| COL1  | COL2   |
+<font color="#0000ff">-------+--------+</font>
| hello | <font color="#ff00ff">123</font>.<font color="#ff00ff">45</font> |
+<font color="#0000ff">-------+--------+</font>
<font color="#ff00ff">1</font> <font color="#6b59ce">row</font> <font color="#a52829"><b>in</b></font> <font color="#a52829"><b>set</b></font> (<font color="#ff00ff">0</font>.<font color="#ff00ff">09</font> sec)


mysql&gt; <font color="#a52829"><b>drop</b></font> <font color="#6b59ce">table</font> testtable;
Empty <font color="#a52829"><b>set</b></font> (<font color="#ff00ff">0</font>.<font color="#ff00ff">21</font> sec)


mysql&gt; quit;

</pre>
</blockquote>

<br>
<a name="daemons"></a>
<span class="heading2">Using the drop-in replacement library with daemons</span><br>

<p>Using the SQL Relay drop-in replacement library for MySQL with daemons is
simlar to using it on the command line.  You just need to add the LD_PRELOAD
command to the startup script for the daemon before the command that starts the
daemon itself.</p>

<p>Unfortunately this approach does not work with PHP.  See the section below
for how to use the drop-in replacement library with PHP.</p>

<br>
<a name="inetd"></a>
<span class="heading2">Using the drop-in replacement library with inetd/xinetd helper programs</span><br>

<p>Inetd and xinetd are daemons that listen on ports and run helper programs to
service requests on those ports.  The helper programs die off after the request
is serviced.</p>

<p>The easist way to get an inetd helper program to use the SQL Relay drop-in
replacement library for MySQL is to add the LD_PRELOAD command to the startup
script for inetd/xinetd.  Any command that inetd/xinetd runs will also preload
the library.</p>

<p>However, if some of the helper programs need to actually run against MySQL
and not against SQL Relay, then you will have to do something different.  The
easiest thing to do is create a script for each helper program that needs to 
run against SQL Relay that runs the LD_PRELOAD command and then runs the actual
helper program, passing it all the necessary command line arguments.</p>

<p>For example, lets say you have a pop3 server called pop3d that uses MySQL
for user identification and you wanted to use SQL Relay instead of MySQL.  The
inetd.conf entry might look like this:</p>

<blockquote><pre>
pop3 stream tcp nowait root /usr/local/bin/pop3d
</pre></blockquote>

<p>An /etc/xinetd.d entry might look like this:

<blockquote><pre>
service pop3
{
	socket_type	= stream
	wait		= no
	user		= root
	server		= /usr/local/bin/pop3d
}
</pre></blockquote>

<p>You could write the a script called /usr/local/bin/pop3d-sqlrelay as
follows:</p>

<blockquote>
<pre>
<font color="#0000ff">#!/bin/sh</font>
<font color="#008a8c">LD_PRELOAD</font>=/usr/local/firstworks/lib/libmysql3sqlrelay.so
<font color="#a52829"><b>export </b></font><font color="#008a8c">LD_PRELOAD</font>
/usr/local/bin/pop3d <font color="#a520f7">$@</font>
</pre>
</blockquote>

<p>And modify the entries to call the script instead of pop3d as follows:</p>

<blockquote><pre>
pop3 stream tcp nowait root /usr/local/bin/pop3d-sqlrelay
</pre></blockquote>

<p>Or for xinetd:</p>

<blockquote><pre>
service pop3
{
	socket_type	= stream
	wait		= no
	user		= root
	server		= /usr/local/bin/pop3d-sqlrelay
}
</pre></blockquote>

<br>
<a name="php"></a>
<span class="heading2">Using the drop-in replacement library with PHP</span><br>

<p>Ideally, if you wanted to use the drop-in replacement library for MySQL with
PHP, you'd just add the LD_PRELOAD command to the startup script for the http
daemon, but PHP is not typically linked against the MySQL client library,
rather the PHP source code includes it's own MySQL client API which is compiled
directly into the PHP module itself.</p>

<p>So, to use the drop-in replacement library with PHP, you must rebuild PHP
and tell it to link against the MySQL client library.</p>

<p>Follow the instructions at <a href="http://www.php.net/manual/en/install.php">PHP: Installation and Configuration</a> for downloading and extracting the
PHP source code.  When running the <i>./configure,</i> script, in addition to
whatever other options you use, make sure to use the following option:</p>

<blockquote><b>
--with-mysql=shared
</b></blockquote>

<p>If you want to use the improved MySQL API, use:</p>

<blockquote><b>
--with-mysqli=shared
</b></blockquote>

<p>as well.  If your mysql_config program is located somewhere other than
/usr/bin, then you will need to specify it's path as well.  For instance, if
it's installed in /usr/local/bin, then you may use the following options:</p>

<blockquote><b>
--with-mysql=shared,/usr/local/bin/mysql_config --with-mysqli=shared,/usr/local/bin/mysql_config
</b></blockquote>

<p>After the configure script has run, you must edit the Makefile by
hand and replace all references to libmysqlclient with references to one of
the drop-in replacement libraries.  For instance, if libmysqlclient.so is found
in /usr/lib/mysql on your system, and you want to use the drop-in replacement
library for MySQL version 5.0 then you'll need to make the following
replacements:</p>

<ul>
<li>replace <b>-Wl,-rpath,/usr/lib/mysql</b> with <b>-Wl,-rpath,/usr/local/firstworks/lib</b></li>
<li>replace <b>-L/usr/lib/mysql</b> with <b>-L/usr/local/firstworks/lib</b></li>
<li>replace <b>-lmysqlclient</b> with <b>-lmysql50sqlrelay</b></li>
</ul>

<p>Afterward you may continue to build and install PHP according to the
instructions.</p>

<p>Afterward, you should edit the <b>php.ini</b> file and configure it to load
the <b>mysql.so</b> module automatically.  When MySQL was compiled into PHP, 
the MySQL API calls could be made without loading the module, but now that it
is not compiled into PHP, the module must be loaded manually.  Adding the
command to load it automatically in the <b>php.ini</b> file will prevent you
from having to go and add <b>dl("mysql.so");</b> to all of your programs.  To
automatically load the MySQL module, add a line like the following to 
<b>php.ini</b>.</p>

<blockquote><b>
extension=mysql.so
</b></blockquote>

<p>A common thing to forget when configuring <b>php.ini</b> is to set the
<b>extension_dir</b> parameter.  By default it's usually set to "./" which is
wrong.  If you installed PHP into /usr/local, then the extension directory will
be something like /usr/local/lib/php/extensions/no-debug-non-zts-20060613.  On
your platform, it may be something else, but similar.  Whatever the directory
name, it should contain the file <b>mysql.so</b>.  Edit <b>php.ini</b>,
search for the <b>extension_dir</b> parameter and set it to your extension
directory.  For example:</p>

<blockquote><b>
extension_dir=/usr/local/lib/php/extensions/no-debug-non-zts-20060613
</b></blockquote>

<p>After following these steps, your PHP apps which formerly used MySQL directly
will now use SQL Relay.  You will need to change the connection parameters, to
point to SQL Relay , but otherwise it should work.</p>

<br>
<a name="modules"></a>
<span class="heading2">Using the drop-in replacement library with modules</span><br>

<p>You may want to use the SQL Relay drop-in replacement library for MySQL
clients with a program that isn't compiled against the native MySQL client
library but rather loads it as a module such as a program that uses ODBC or
Perl DBI, or an Apache/PHP application.</p>

<p>Using the SQL Relay drop-in replacement library with programs that load
the native MySQL client library as a module is simlar to using it on the
command line.  You just need to make sure that the LD_PRELOAD command is run
before the program starts.</p>

<p>If the program is a command line program, then run the LD_PRELOAD command
before running your program.  Even though the program ultimately loads the
native MySQL client library, all of its functions will be overriden by the
SQL Relay drop-in replacement library.</p>

<p>If the program is a daemon then add the LD_PRELOAD command to the startup
script for the daemon.</p>

<p>If the program runs in the address space of a daemon, such as a PHP
application running under Apache's mod_php, then add the LD_PRELOAD command to
the startup script for the daemon.  The caveat here is that all applications
running in the address space of the daemon will use the drop-in replacement
library instead of the native MySQL library.  It is not possible, for example
for a web server to run one PHP application directly against MySQL and another
PHP application against SQL Relay using the drop-in replacement library; if the
drop-in replacement library is loaded, both applications will end up using
it.</p>

<p>If the program is spawned by a daemon, such as a cgi spawned by a web-server
or an inetd/xinetd helper program, then you can either add the LD_PRELOAD
command to the daemon's startup script or write a script to run the LD_PRELOAD
command and pass along the command line arguments (see the section
<a href="#inetd">Using the drop-in replacement library with inetd/xinetd helper
programs above)</a>).</p>

<br>
<a name="work"></a>
<span class="heading2">Function support</span><br>

<p>The SQL Relay drop-in replacement library for MySQL implements most of the
native MySQL client library's functions, but there are a few functions that
aren't implemented because SQL Relay doesn't have a good way to support them.
These functions return safe values or a failure condition.</p>

<p>Here is a list of functions that are implemented and functions that are not.
If your application uses one of the functions that is not implemented, you may
or may not be able to use it with the SQL Relay drop-in replacement library for
MySQL.</p>

<table border="1">
<tr><th>Function</th><th>Implemented?</th></tr>
<tr><td>mysql_thread_safe</td><td>always returns 1</td></tr>
<tr><td>mysql_init</td><td>yes</td></tr>
<tr><td>mysql_set_server_option</td><td>does nothing but always returns success</td></tr>
<tr><td>mysql_options</td><td>does nothing but always returns success</td></tr>
<tr><td>mysql_ssl_set</td><td>does nothing but always returns success</td></tr>
<tr><td>mysql_connect</td><td>yes</td></tr>
<tr><td>mysql_real_connect</td><td>yes</td></tr>
<tr><td>mysql_close</td><td>yes</td></tr>
<tr><td>mysql_ping</td><td>yes</td></tr>
<tr><td>mysql_stat</td><td>returns a string similar to the real mysql_stat but with empty values</td></tr>
<tr><td>mysql_shutdown</td><td>always returns CR_UNKNOWN_ERROR</td></tr>
<tr><td>mysql_reload</td><td>yes</td></tr>
<tr><td>mysql_refresh</td><td>only implemented for refresh_options==REFRESH_GRANT</td></tr>
<tr><td>mysql_thread_id</td><td>always returns 0</td></tr>
<tr><td>mysql_list_processes</td><td>always returns NULL</td></tr>
<tr><td>mysql_kill</td><td>always returns CR_UNKNOWN_ERROR</td></tr>
<tr><td>mysql_get_client_info</td><td>returns the version string of the client that the library emulates</td></tr>
<tr><td>mysql_get_client_version</td><td>returns the version number of the client that the library emulates</td></tr>
<tr><td>mysql_get_host_info</td><td>returns an empty string</td></tr>
<tr><td>mysql_get_proto_info</td><td>returns the protocol version number of the client that the libary emulates</td></tr>
<tr><td>mysql_get_server_info</td><td>returns the version string of the client that the library emulates</td></tr>
<tr><td>mysql_get_server_version</td><td>returns the version number of the client that the libary emulates</td></tr>
<tr><td>mysql_change_user</td><td>yes</td></tr>
<tr><td>mysql_character_set_name</td><td>always returns latin1</td></tr>
<tr><td>mysql_set_character_set</td><td>does nothing, returns success</td></tr>
<tr><td>mysql_debug</td><td>does nothing</td></tr>
<tr><td>mysql_dump_debug_info</td><td>always returns failure</td></tr>
<tr><td>mysql_create_db</td><td>always returns failure</td></tr>
<tr><td>mysql_select_db</td><td>always returns failure</td></tr>
<tr><td>mysql_drop_db</td><td>always returns failure</td></tr>
<tr><td>mysql_list_dbs</td><td>always returns NULL</td></tr>
<tr><td>mysql_list_tables</td><td>always returns NULL</td></tr>
<tr><td>mysql_escape_string</td><td>yes</td></tr>
<tr><td>mysql_odbc_escape_string</td><td>always returns NULL</td></tr>
<tr><td>myodbc_remove_escape</td><td>does nothing</td></tr>
<tr><td>mysql_query</td><td>yes</td></tr>
<tr><td>mysql_send_query</td><td>yes</td></tr>
<tr><td>mysql_read_query_result</td><td>yes</td></tr>
<tr><td>mysql_real_escape_string</td><td>implemented but only for utf-8 character set</td></tr>
<tr><td>mysql_real_query</td><td>yes</td></tr>
<tr><td>mysql_info</td><td>always returns an empty string</td></tr>
<tr><td>mysql_insert_id</td><td>always returns 0</td></tr>
<tr><td>mysql_store_result</td><td>yes</td></tr>
<tr><td>mysql_use_result</td><td>yes</td></tr>
<tr><td>mysql_free_result</td><td>yes</td></tr>
<tr><td>mysql_more_results</td><td>always returns false</td></tr>
<tr><td>mysql_next_result</td><td>always returns -1</td></tr>
<tr><td>mysql_list_fields</td><td>always returns NULL</td></tr>
<tr><td>mysql_num_fields</td><td>yes</td></tr>
<tr><td>mysql_fetch_field</td><td>yes</td></tr>
<tr><td>mysql_fetch_fields</td><td>yes</td></tr>
<tr><td>mysql_fetch_field_direct</td><td>yes</td></tr>
<tr><td>mysql_fetch_lengths</td><td>yes</td></tr>
<tr><td>mysql_field_count</td><td>yes</td></tr>
<tr><td>mysql_field_seek</td><td>yes</td></tr>
<tr><td>mysql_field_tell</td><td>yes</td></tr>
<tr><td>mysql_num_rows</td><td>yes</td></tr>
<tr><td>mysql_affected_rows</td><td>yes</td></tr>
<tr><td>mysql_row_seek</td><td>yes</td></tr>
<tr><td>mysql_row_tell</td><td>yes</td></tr>
<tr><td>mysql_data_seek</td><td>yes</td></tr>
<tr><td>mysql_fetch_row</td><td>yes</td></tr>
<tr><td>mysql_eof</td><td>yes</td></tr>
<tr><td>mysql_warning_count</td><td>always returns 0</td></tr>
<tr><td>mysql_errno</td><td>yes</td></tr>
<tr><td>mysql_error</td><td>returns the SQL Relay error string</td></tr>
<tr><td>mysql_sqlstate</td><td>always returns an empty string</td></tr>
<tr><td>mysql_commit</td><td>yes</td></tr>
<tr><td>mysql_rollback</td><td>yes</td></tr>
<tr><td>mysql_autocommit</td><td>yes</td></tr>
<tr><td>mysql_prepare</td><td>yes</td></tr>
<tr><td>mysql_bind_param</td><td>yes, for all types except INT24 and GEOMETRY</td></tr>
<tr><td>mysql_bind_result</td><td>yes</td></tr>
<tr><td>mysql_execute</td><td>yes</td></tr>
<tr><td>mysql_param_count</td><td>yes</td></tr>
<tr><td>mysql_param_result</td><td>no, the MySQL docs don't even explain what this should do</td></tr>
<tr><td>mysql_fetch</td><td>yes</td></tr>
<tr><td>mysql_fetch_column</td><td>no, the MySQL docs don't even explain what this should do</td></tr>
<tr><td>mysql_get_metadata</td><td>yes</td></tr>
<tr><td>mysql_send_long_data</td><td>always returns false</td></tr>
<tr><td>mysql_stmt_num_rows</td><td>yes</td></tr>
<tr><td>mysql_stmt_affected_rows</td><td>yes</td></tr>
<tr><td>mysql_stmt_row_seek</td><td>yes</td></tr>
<tr><td>mysql_stmt_row_tell</td><td>yes</td></tr>
<tr><td>mysql_stmt_data_seek</td><td>yes</td></tr>
<tr><td>mysql_stmt_close</td><td>yes</td></tr>
<tr><td>mysql_stmt_errno</td><td>yes</td></tr>
<tr><td>mysql_stmt_error</td><td>returns the SQL Relay error string</td></tr>
<tr><td>mysql_stmt_sqlstate</td><td>always returns an empty string</td></tr>
<tr><td>mysql_stmt_store_result</td><td>yes</td></tr>
<tr><td>mysql_stmt_free_result</td><td>yes</td></tr>
<tr><td>mysql_stmt_reset</td><td>yes</td></tr>
<tr><td>mysql_server_init</td><td>does nothing</td></tr>
<tr><td>mysql_library_init</td><td>does nothing</td></tr>
<tr><td>mysql_server_end</td><td>does nothing</td></tr>
<tr><td>mysql_library_end</td><td>does nothing</td></tr>
</table>

<p>The native MySQL client API also defines several data structures.
Applications are supposed to access fields of the MYSQL_FIELD and MYSQL_BIND
structures directly.  Applications also access MYSQL_ROW's directly, but
MYSQL_ROW is just a typedef for (char **).  The SQL Relay drop-in replacement
library for MySQL supports MYSQL_ROW and the following fields of MYSQL_FIELD and
MYSQL_BIND.  Note that the MYSQL_BIND structure is only available when emulating
MySQL 4.1, 5.0 or 5.1 and that the fields of MYSQL_FIELD that are available
depend on whether the drop-in library is emulating MySQL 3, 4.0, 4.1, 5.0 or
5.1</p>

<table><tr><td valign="top">

<table border="1">
<tr><th colspan="2">MYSQL_FIELD</th></tr>
<tr><th>Field</th><th>Supported?</th></tr>
<tr><td>name</td><td>yes</td></tr>
<tr><td>org_name</td><td>no, is always set to the same value as name</td></tr>
<tr><td>table</td><td>no, is always set to an empty string</td></tr>
<tr><td>org_table</td><td>no, is always set to an empty string</td></tr>
<tr><td>db</td><td>no, is always set to an empty string</td></tr>
<tr><td>catalog</td><td>no, is always set to an empty string</td></tr>
<tr><td>def</td><td>no, is always set to an empty string</td></tr>
<tr><td>length</td><td>yes</td></tr>
<tr><td>max_length</td><td>yes</td></tr>
<tr><td>name_length</td><td>yes</td></tr>
<tr><td>org_name_length</td><td>yes, but is always set to the length of name</td></tr>
<tr><td>table_length</td><td>no, is always set to 0</td></tr>
<tr><td>org_table_length</td><td>no, is always set to 0</td></tr>
<tr><td>db_length</td><td>no, is always set to 0</td></tr>
<tr><td>catalog_length</td><td>no, is always set to 0</td></tr>
<tr><td>def_length</td><td>no, is always set to 0</td></tr>
<tr><td>flags</td><td>yes</td></tr>
<tr><td>decimals</td><td>yes</td></tr>
<tr><td>charsetnr</td><td>no, is always set to 0</td></tr>
<tr><td>type</td><td>yes</td></tr>
</table>

</td><td valign="top">

<table border="1">
<tr><th colspan="2">MYSQL_BIND</th></tr>
<tr><th>Field</th><th>Supported?</th></tr>
<tr><td>length</td><td>yes</td></tr>
<tr><td>is_null</td><td>yes</td></tr>
<tr><td>buffer</td><td>yes</td></tr>
<tr><td>buffer_type</td><td>yes</td></tr>
<tr><td>buffer_length</td><td>yes</td></tr>
<tr><td>inter_buffer</td><td>no</td></tr>
<tr><td>offset</td><td>no</td></tr>
<tr><td>internal_length</td><td>no</td></tr>
<tr><td>param_number</td><td>no</td></tr>
<tr><td>long_data_used</td><td>no</td></tr>
<tr><td>binary_data</td><td>no</td></tr>
<tr><td>null_field</td><td>no</td></tr>
<tr><td>internal_is_null</td><td>no</td></tr>
<tr><td>store_param_func</td><td>no</td></tr>
<tr><td>fetch_result</td><td>no</td></tr>
</table>

</td></tr></table>

</body>
</html>
